libobs_simple\sources\windows\sources/
monitor_capture.rs1use super::ObsDisplayCaptureMethod;
5use crate::define_object_manager;
6use display_info::DisplayInfo;
9use libobs_simple_macro::obs_object_impl;
10use libobs_wrapper::{
11 data::{ObsObjectBuilder, ObsObjectUpdater},
12 scenes::ObsSceneRef,
13 sources::{ObsSourceBuilder, ObsSourceRef},
14 unsafe_send::Sendable,
15 utils::ObsError,
16};
17use num_traits::ToPrimitive;
18use std::ffi::CStr;
19
20define_object_manager!(
22 #[derive(Debug)]
24 struct MonitorCaptureSource("monitor_capture") for ObsSourceRef {
25 #[obs_property(type_t = "string", settings_key = "monitor_id")]
26 monitor_id_raw: String,
27
28 #[obs_property(type_t = "bool")]
29 capture_cursor: bool,
31
32 #[obs_property(type_t = "bool")]
33 compatibility: bool,
35
36 #[obs_property(type_t = "bool")]
37 force_sdr: bool,
39
40 capture_method: Option<ObsDisplayCaptureMethod>,
41 }
42);
43
44const AUDIO_SOURCE_TYPE: &CStr = c"wasapi_process_output_capture";
45fn audio_capture_available() -> bool {
46 unsafe { !libobs::obs_get_latest_input_type_id(AUDIO_SOURCE_TYPE.as_ptr()).is_null() }
47}
48
49#[obs_object_impl]
50impl MonitorCaptureSource {
51 pub fn get_monitors() -> anyhow::Result<Vec<Sendable<DisplayInfo>>> {
53 Ok(DisplayInfo::all()?.into_iter().map(Sendable).collect())
54 }
55
56 pub fn set_monitor(self, monitor: &Sendable<DisplayInfo>) -> Self {
57 self.set_monitor_id_raw(monitor.0.name.as_str())
58 }
59
60 pub fn set_capture_audio(mut self, capture_audio: bool) -> anyhow::Result<Self, String> {
61 if capture_audio && !audio_capture_available() {
62 return Err("Game Audio Capture is not available on this system".to_string());
63 }
64
65 self.get_settings_updater()
66 .set_bool_ref("capture_audio", capture_audio);
67
68 Ok(self)
69 }
70}
71
72impl<'a> MonitorCaptureSourceUpdater<'a> {
73 pub fn set_capture_method(mut self, method: ObsDisplayCaptureMethod) -> Self {
74 self.get_settings_updater()
75 .set_int_ref("method", method.to_i32().unwrap() as i64);
76
77 self
78 }
79}
80
81impl MonitorCaptureSourceBuilder {
82 pub fn set_capture_method(mut self, method: ObsDisplayCaptureMethod) -> Self {
86 self.capture_method = Some(method);
87 self
88 }
89}
90
91impl ObsSourceBuilder for MonitorCaptureSourceBuilder {
92 fn add_to_scene(mut self, scene: &mut ObsSceneRef) -> Result<ObsSourceRef, ObsError>
93 where
94 Self: Sized,
95 {
96 self.get_settings_updater().set_int_ref(
98 "method",
99 ObsDisplayCaptureMethod::MethodWgc.to_i32().unwrap() as i64,
100 );
101
102 let method_to_set = self.capture_method;
103 let runtime = self.runtime.clone();
104
105 let b = self.build()?;
106 let mut res = scene.add_source(b)?;
107
108 if let Some(method) = method_to_set {
109 MonitorCaptureSourceUpdater::create_update(runtime, &mut res)?
110 .set_capture_method(method)
111 .update()?;
112 }
113
114 Ok(res)
115 }
116}